﻿using DinletBilsin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace DinletBilsin.WebService
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
            
            LoadCacheData();
          
        }

        private void LoadCacheData()
        {
            LoadFromBinary(HttpContext.Current.Server.MapPath("~/App_Data") + "\\index.db");

            HttpRuntime.Cache.Insert("hashMap", hashMap, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
            HttpRuntime.Cache.Insert("songNames", songNames, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
            HttpRuntime.Cache.Insert("songNameSet", songNameSet, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);

           // File.WriteAllLines("C:\\sarkilar.txt", songNames);
        
        }

        private static int BINARY_HEADER = -1;

        private List<string> songNames = new List<string>();
        private Dictionary<long, List<FingerPrint>> hashMap = new Dictionary<long, List<FingerPrint>>();
        private HashSet<string> songNameSet = new HashSet<string>();
        public void LoadFromBinary(string fileName)
        {
            try
            {
                using (FileStream fr = new FileStream(fileName, FileMode.Open))
                {
                    BinaryReader br = new BinaryReader(fr);
                    songNames.Clear();

                    int header = br.ReadInt32();
                    if (header != BINARY_HEADER)
                    {
                        throw new InvalidDataException("Invalid binary index file!");
                    }

                    int nameCount = br.ReadInt32();
                    for (int i = 0; i < nameCount; i++)
                    {
                        string name = br.ReadString();
                        songNames.Add(name);
                        //if (CheckDuplicate)
                        //    songNameSet.Add(name);
                    }

                    hashMap.Clear();
                    int hashCount = br.ReadInt32();
                    for (int i = 0; i < hashCount; i++)
                    {
                        long key = br.ReadInt64();
                        int count = br.ReadInt32();

                        List<FingerPrint> pointList = new List<FingerPrint>(count);
                        for (int j = 0; j < count; j++)
                        {
                            short time = br.ReadInt16();
                            short songID = br.ReadInt16();
                            FingerPrint dataPoint = new FingerPrint(time, songID);
                            pointList.Add(dataPoint);
                        }

                        hashMap.Add(key, pointList);
                    }
                }
                HttpRuntime.Cache.Insert("CacheLoaded", true, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
            }
            catch (Exception e)
            {
                HttpRuntime.Cache.Insert("CacheLoaded", false, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);  
                Trace.WriteLine(e.Message);
                Trace.WriteLine(e.StackTrace);
                throw new InvalidDataException(e.Message);
            }
        }       
    }
}